package main

import (
	"fmt"
	"math/rand"
)

type Job struct {
	Id      int
	RandNum int
}

type Result struct {
	job *Job
	sum int
}

func createPool(num int, jobChan chan *Job, resultChan chan *Result) {
	for i := 0; i < num; i++ {
		go func(jobChan chan *Job, result chan *Result) {
			for job := range jobChan {
				rNum := job.RandNum

				// do something
				var sum int
				for rNum != 0 {
					tmp := rNum % 10
					sum += tmp
					rNum /= 10
				}
				// done

				resultChan <- &Result{
					job: job,
					sum: sum,
				}
			}
		}(jobChan, resultChan)
	}
}

func main() {
	numChan := 128
	jobChan := make(chan *Job, numChan)
	resultChan := make(chan *Result, numChan)

	createPool(numChan, jobChan, resultChan)

	go func(resultChan chan *Result) {
		for result := range resultChan {
			fmt.Printf("job id:%v random number:%v result:%d\n", result.job.Id, result.job.RandNum, result.sum)
		}
	}(resultChan)

	var id int
	for {
		id++
		rNum := rand.Int()
		jobChan <- &Job{
			Id:      id,
			RandNum: rNum,
		}
	}
}
